/**
 * 字符串格式化
 * @param param {Array|Object|arguments}
 * eg. '欢迎{0}'.format('xp')   result:欢迎xp
 * eg. '欢迎{0},年龄为{1}'.format('xp','18') result:欢迎xp,年龄为18
 * eg. '欢迎{name},年龄为{age}'.format({'name':'xp','age':'18'}) result:欢迎xp,年龄为18
 * eg. '欢迎{name},年龄为{age}'.format({'name': 'xp', 'age': function (attr) {
            console.log(attr);
            return '18';
        }});result:控制台会输出age,格式化后得到的新的字符串是：欢迎xp,年龄为18
 * @returns {String} 格式化后的字符串
 */
String.prototype.format = function (param) {
    var value = String(this);
    var args = arguments,
        proto = Object.prototype.toString;

    if (args.length) {
        args = args.length == 1 ?
            (param !== null && (/\[object Array\]|\[object Object\]/.test(proto.call(param))) ? param : args) : args;
        return value.replace(/\{(\w+)}/g, function (pattern, name) {
            var val = args != undefined ? args[name] : '';
            if (typeof val == 'function') {
                val = val(name);
            }
            return ("undefined" == typeof val ? "" : val)
        })
    }
    return value;
};

/**
 * ==================================================
 * Date数据类型方法扩展
 * ==================================================
 *
 */
/**
 * 日期转字符串
 * @param format {?String} 默认yyyy-MM-dd
 * @returns {*|String}
 * eg. (new Date()).format() result: 2014-10-10
 * eg. (new Date()).format('yyyy/MM/dd hh:mm:ss:S') result: 2014/10/10 17:17:27:616
 * eg. (new Date()).format('yyyy年第q季度 MM月dd日 hh时mm分ss秒S') result:2014年第4季度 10月10日 17时19分51秒381
 */
Date.prototype.format = function (format) {
    format = format || "yyyy-MM-dd";
    var o = {
        "M+": this.getMonth() + 1,  //月份
        "d+": this.getDate(),     //日
        "h+": this.getHours(),    //小时
        "m+": this.getMinutes(),  //分钟
        "s+": this.getSeconds(), //秒
        "q+": Math.floor((this.getMonth() + 3) / 3),  //季度
        "S": this.getMilliseconds() //毫秒
    };

    if (/(y+)/.test(format)) {
        format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    }

    for (var k in o) {
        if (new RegExp("(" + k + ")").test(format)) {
            format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
        }
    }
    return format;
};

/**
 *  截取时间至日期
 * @returns {Date}
 * eg. (new Date()).trunc() result: Fri Oct 10 2014 00:00:00 GMT+0800 (中国标准时间) 时分秒都为0的日期
 */
Date.prototype.trunc = function () {
    return new Date(this.getFullYear(), this.getMonth(), this.getDate());
};

/**
 * 日期加减
 * @param addType {string} 加减的类型，如年份、季度、月份等
 * @param addValue {number} 加减的具体值,正整数代表加，反之为减
 * @returns {*} 加减后返回新的日期
 * eg. (new Date()).dateAdd('m',1) 月份加1
 * eg. (new Date()).dateAdd('y',-1) 年份减1
 */
Date.prototype.dateAdd = function (addType, addValue) {
    if (isNaN(addValue)) {
        throw new Error("输入的加减数必须为数字！");
    }
    switch (addType.toLowerCase()) {
        case "y":  //年
            this.setFullYear(this.getFullYear() + addValue);
            break;
        case "q":  //季度
            this.setMonth(this.getMonth() + addValue * 3);
            break;
        case "m":  //月
            this.setMonth(this.getMonth() + addValue);
            break;
        case "w":  //周
            this.setDate(this.getDate() + addValue * 7);
            break;
        case "d":  //日
            this.setDate(this.getDate() + addValue);
            break;
        case "h":  //小时
            this.setHours(this.getHours() + addValue);
            break;
        case "mi":  //秒
            this.setMinutes(this.getMinutes() + addValue);
            break;
        case "s":  //分
            this.setSeconds(this.getSeconds() + addValue);
            break;
        case "ms":  //毫秒
            this.setMilliseconds(this.getMilliseconds() + addValue);
            break;
        default:
            throw new Error("输入的类型参数出错！必须为以下情况之一：\r\n年(y)、季度(q)、月(m)、周(w)、日(d)、小时(h)、分钟(mi)、秒(s)、毫秒(ms)。");
    }

    return this;
};

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (item, fromIndex) {
        var i = 0, length = this.length;
        if (fromIndex !== undefined) {
            if (fromIndex >= 0) {
                i = fromIndex;
            } else {
                i = length + fromIndex;
            }
        }
        for (; i < length; i++) if (this[i] === item) {
            return i;
        }
        return -1;
    }
}

/**************************************
 *$新增常用的方法
 *
 ***************************************/
(function () {
    var _projectName = (function () {
        var pathName = window.location.pathname;
        return pathName.substring(0, pathName.substr(1).indexOf('/') + 1);
    }());

    var __defaultMaskInfo = '数据加载中...';
    var loadMaskTemp = '<div class="loadMask-wrap">' +
        '                   <div class="mask-info"><img src="' + _projectName + '/content/images/loding-min.gif">{0}</div>' +
        '                   <div class="load-background"></div>' +
        '               </div>';

    function createMask(target, html) {
        var $mask = $(target).find('>.loadMask-wrap');
        if ($mask.length) {
            $mask.data('mask-count', $mask.data('mask-count') + 1);
        }else{
            $mask = $(html).appendTo($(target));
            if ($(target).css('position') == '' || $(target).css('position') == 'static') {
                $(target).css('position','relative');
            }
            $mask.data('mask-count', 1);
        }
        return $mask;
    }

    function removeMask(target) {
        var $mask = $(target).find('>.loadMask-wrap');
        if ($mask.length) {
            var count = $mask.data('mask-count');
            if (count == 1) {
                $mask.remove();
            }else{
                $mask.data('mask-count', count - 1);
            }
        }
    }

    $.ajaxSettings.traditional = true;//jQuery 参数格式化方式 true传统方式，其它为非传统方式
    $.extend({
        getProjectName: function () {
            return _projectName;
        },
        ajaxExt: function (setting) {
            var dtd = $.Deferred();
            var defaultSetting = {
                urlPrefix: $.getProjectName(),
                type: 'POST',
                dataType: 'JSON'
            };

            var loadMaskTarget;//遮罩层放置的目标对象
//            if (setting.loadMask) {
//
//                delete  setting.loadMask;
//            }
            $.extend(defaultSetting, setting);
            defaultSetting.url = defaultSetting.urlPrefix + defaultSetting.url;

            var success = null;
            if (defaultSetting.success) {
                success = defaultSetting.success;
            }
            defaultSetting.success = function (result) {
//                if (loadMask) {
//                    loadMask.remove();
//                }

                loadMaskTarget && removeMask(loadMaskTarget);
                if (result.success === false) {
                    if (result.msgType == '1') {
                        window.parent.location = $.getProjectName() + '/logon/commonQuit.htm';
                    }
                    if (result.msgType == '2' && result.msg) {
                        $.messager.alert("警告", result.msg, "warning");
                    }
                    if (result.msgType == '3' && result.msg) {
                        $.messager.alert("错误", result.msg, "error");
                    }
                    dtd.reject();
                } else {
                    if (result.success === true && result.msg) {
                        $.messager.alert("成功", result.msg, "success");
                    }
                    if (typeof success === 'function') {
                        success(result.obj);
                    }
                    dtd.resolve(result.obj);// 更新执行状态：已完成
                }
            };
            var error = null;
            if (defaultSetting.error) {
                error = defaultSetting.error;
            }
            defaultSetting.error = function (XMLHttpRequest, textStatus, errorThrown) {
//                if (loadMask) {
//                    loadMask.remove();
//                }
                loadMaskTarget && removeMask(loadMaskTarget);
                if (typeof error === 'function') {
                    error(XMLHttpRequest, textStatus, errorThrown);
                }
                dtd.reject(XMLHttpRequest, textStatus, errorThrown);//更新执行状态：已失败
            };

            if (defaultSetting.loadMask) {
                var html = loadMaskTemp.format(defaultSetting.loadMask.msg || __defaultMaskInfo);
                loadMaskTarget = defaultSetting.loadMask.target || $('body');
                createMask(loadMaskTarget, html);
            }

            $.ajax(defaultSetting);
            return dtd.promise();
        },
        /**
         * 字符串转JSON【适用于字符串不是标准的JSON格式】，标准的字符串格式请使用$.parseJSON
         * @param str
         * @returns {JSON}
         */
        strToJson: function (str) {
            if (str === '') {
                return;
            }
            return (new Function('return ' + str))();
        },
        /**
         * 获取html元素对应的style的值
         * @param el
         * @param key
         * @returns {number}
         */
        getStyleNum: function (el, key) {
            var style = $(el).css(key),
                val = /-{0,1}\d+/.exec(style);
            return ~~val;
        },
        getWidthByParent: function (el) {
            var $parent = $(el).parent();
            var borderWidth = this.getStyleNum($parent, 'border-left-width') + this.getStyleNum($parent, 'border-right-width');
            var paddingWidth = this.getStyleNum($parent, 'padding-left') + this.getStyleNum($parent, 'padding-right');
            return $parent.width() - paddingWidth - borderWidth;
        },
        getHeightByParent: function (el) {
            var $parent = $(el).parent();
            var borderHeight = this.getStyleNum(el, 'border-top-width') + this.getStyleNum(el, 'border-bottom-width');
            var paddingHeight = this.getStyleNum(el, 'padding-top') + this.getStyleNum(el, 'padding-bottom');
            return $parent.height() - borderHeight - paddingHeight;
        },
        /**
         * 设置html元素宽度，去除border左右宽度和padding左右的值、margin-left、margin-right
         * @param el {HTMLElement}
         * @param val 总宽度
         */
        setWidthExceptBPM: function (el, val) {
            var $el = $(el);
            var borderWidth = this.getStyleNum(el, 'border-left-width') + this.getStyleNum(el, 'border-right-width');
            var paddingWidth = this.getStyleNum(el, 'padding-left') + this.getStyleNum(el, 'padding-right');
            var marginWidth = this.getStyleNum(el, 'margin-left') + this.getStyleNum(el, 'margin-right');

            $el.width(val - borderWidth - paddingWidth - marginWidth);
        },
        /**
         * 设置html元素高度，去除border上下高度和padding上下的值、margin-top、margin-bottom
         * @param el {HTMLElement}
         * @param val 总高度
         */
        setHeightExceptBPM: function (el, val) {
            var $el = $(el);
            var borderHeight = this.getStyleNum(el, 'border-top-width') + this.getStyleNum(el, 'border-bottom-width');
            var paddingHeight = this.getStyleNum(el, 'padding-top') + this.getStyleNum(el, 'padding-bottom');
            var marginHeight = this.getStyleNum(el, 'margin-top') + this.getStyleNum(el, 'margin-bottom');

            $el.height(val - borderHeight - paddingHeight - marginHeight);
        },
        /**
         * 延迟执行函数
         * 主要用于特定场景下具体的函数没有加载完成，需要等待加载完成后才能执行
         * @param fn {string} 需要延迟执行的具体函数名称
         *  执行的具体函数的具体参数
         * e.g commonFun.deferExecuteFn('fnName','1','2',....)
         */
        deferExecuteFn: function (fn) {
            var dtd = $.Deferred(); // 生成Deferred对象

            var win = $.isWindow(this) ? this : window;
            var wait = function (dtd) {
                var tasks = function () {

                    if (typeof (win[fn.funcName]) !== "undefined") {
                        dtd.resolve(); // 改变Deferred对象的执行状态
                    } else {
                        setTimeout(tasks, 200);
                    }
                };
                setTimeout(tasks, 200);
            };
            dtd.promise(wait);
            wait.done(function () {
                fn.call(win);
            });
            wait(dtd);
        },
        execIframeFn: function (iframe, fnName) {
            var args = $.makeArray(arguments).slice(2);
            var win = iframe.contentWindow;

            if (typeof(win[fnName]) !== "undefined") {
                return win[fnName].apply(win, args);
            }

            var dtd = $.Deferred(); // 生成Deferred对象


            var mask = $.createMask($(iframe).parent());
            var wait = function (dtd) {
                var tasks = function () {
                    wait.num++;
                    if (typeof (win[fnName]) !== "undefined") {
                        dtd.resolve(); // 改变Deferred对象的执行状态
                    } else {
                        //wait.num < 100 && setTimeout(tasks, 200);
                        if (wait.num > 100) {
                            dtd.reject();
                        } else {
                            setTimeout(tasks, 200);
                        }
                    }
                };
                setTimeout(tasks, 200);
            };
            wait.num = 1;
            dtd.promise(wait);
            wait.done(function () {
                mask.remove();
                win[fnName].apply(win, args);
            });
            wait.fail(function () {
                mask.remove();
                $.messager.alert('超时', '未找到对应的方法', 'error');
            });
            wait(dtd);
            return dtd;
        },
        createMask: function ($target) {
            $target = $target || $('body');
            var html = loadMaskTemp.format('数据加载中...');
            return createMask($target, html);
        }
    });


    $.extend({
        /**
         * 导出文件
         * @param {String} url
         * @param {Object|Null} params 参数，格式为{arg1:value1,...}
         */
        exportFile: function (url, params) {
            url = $.getProjectName() + url;
            var $form = $('<form style="display: none;" method="post"  target="_blank"></form>');
            if (params) {
                var $input, value;
                for (var name in params) {
                    $input = $('<input type="hidden" name="{0}">'.format(name));
                    value = params[name] === undefined ? '' : params[name];
                    if ($.isArray(value)) {
                        value = value.join(',');
                    }
                    $input.val(value);
                    $input.appendTo($form);
                }
            }
            $form.appendTo($('body'));
            $form.attr('action', url);
            $form.submit();
            setTimeout(function () {
                $form && $form.remove();
            }, 200);
        },
        /**
         * 打开另外一个tab页面（用于界面之间的跳转）
         * @param ｛String｝menuId 菜单ID
         * @param funcName ｛String|Null｝打开tab页面后需要调用的函数的名称
         * @param args｛Array|Null｝调用函数需要用到的参数
         * eg. 1) $.openTab('菜单ID');
         * eg. 2) $.openTab('菜单ID','要调用目标界面的函数名称');
         * eg. 3) $.openTab('菜单ID','要调用目标界面的函数名称',[参数1，参数2。。。]);
         */
        openTab: function (menuId, funcName, args) {
            var func;
            if (funcName) {
                func = function () {
                    this[funcName] && this[funcName].apply(this, args || []);
                };
                func.funcName = funcName;
            }
            window.parent.openTab(menuId, func);
        }
    });

    //操作主界面的方法
    $.extend({
        /**
         * 设置首页选中的线路名称和ID
         * @param lineId
         * @param lineName
         */
        setCurrentLine: function (lineId, lineName) {
            window.parent.$.cookie('homepage_lineId', lineId, {expires: 365});
        },
        /**
         * 设置首页选中的时间类型
         * @param dateType
         */
        setDateType: function (dateType) {
            window.parent.$.cookie('homepage_dateType', dateType, {expires: 365});
        },
        //获取cookie中的lineId
        getLineCookie: function () {
            return window.parent.$.cookie('homepage_lineId');
        },
        //获取cookie中的时间类型
        getDateTypeCookie: function () {
            return window.parent.$.cookie('homepage_dateType');
        }
    })
}(jQuery));

//$.fn扩展
(function ($) {
    $.each(['Width', 'Height'], function (i, name) {
        /**
         * 增加宽度或者高度
         * @param val
         * @returns {jQuery}
         */
        $.fn['add' + name] = function (val) {
            return this[name.toLowerCase()](this[name.toLowerCase()]() + val);
        }
    });

    //placeholder初始化
    var placeholderInit = 'placeholder' in document.createElement('input') ? null : function ($obj) {

        $obj.each(function () {
            var placeholder = $(this).attr('placeholder');
            $(this).on('focus', function () {
                this.style.color = "#333";
                if (this.value === placeholder) {
                    this.value = '';
                }
            }).on('blur', function () {
                if (this.value === '') {
                    this.style.color = "#999";
                    this.value = placeholder;
                }
            }).one('propertychange', function () {
                if (this.value !== placeholder) {
                    this.style.color = "#333";
                }
            }).trigger('blur');
        });
    };

    //报表时间快捷切换事件
    function reportDateSelectChange(el) {
        $(el).on('change', function () {
            var config = $(this).attr('data-options');
            config = $.strToJson(config);
            var $beginDate = $('#' + config.beginDateId);
            $beginDate.val('').unbind('focus');
            switch ($(this).val()) {
                case '1':
                    $beginDate.on('focus', function () {
                        WdatePicker({
                            dateFmt: 'yyyy-MM-dd',
                            firstDayOfWeek: 1,
                            isShowClear: false,
                            onpicked: function () {
                                this.blur();
                            }
                        })
                    });
                    break;
                case '2':
                    $beginDate.on('focus', function () {
                        WdatePicker({
                            dateFmt: 'yyyy-WW周（yyyy-MM-dd~yyyy-MM-dd）',
                            firstDayOfWeek: 1,
                            isShowWeek: true,
                            isShowClear: false,
                            errDealMode: 2,
                            onpicked: function () {
                                var y = $dp.cal.getP('y'); //年
                                var m = $dp.cal.getP('M');//月
                                var d = $dp.cal.getP('d');//日
                                var W = $dp.cal.getP('W');//第几周
                                var w = $dp.cal.getP('w');//星期

                                var chooseDate = new Date(y + '/' + m + '/' + d);
                                var monday = new Date(chooseDate.setDate(chooseDate.getDate() - w + 1));
                                var sunday = new Date(chooseDate.setDate(chooseDate.getDate() + 6));

                                this.blur();
                                if (monday.getFullYear() != sunday.getFullYear()) {
                                    if (W === '01') {
                                        y = sunday.getFullYear();
                                    } else {
                                        y = monday.getFullYear();
                                    }
                                }
                                var str = y + '-' + W + '周' + '（' + monday.format() + '~' + sunday.format() + '）';
                                $(this).val(str);

                                $(this).removeClass('WdateFmtErr');
                            }
                        })
                    });
                    break;
                case '3':
                    $beginDate.on('focus', function () {
                        WdatePicker({
                            autoShowQS: true,
                            firstDayOfWeek: 1,
                            dateFmt: 'yyyy-MM月',
                            isShowClear: false,
                            onpicked: function () {
                                this.blur();
                            }
                        })
                    });
                    break;
                case '4':
                    $beginDate.on('focus', function () {
                        WdatePicker({
                            autoShowQS: true,
                            isShowClear: false,
                            dateFmt: 'yyyy-MM季',
                            firstDayOfWeek: 1,
                            isQuarter: true,
                            isShowOK: true,
                            isShowToday: false,
                            autoPickDate: false,
                            disabledDates: ['....-0[5-9]-..', '....-1[0-2]-..'],
                            startDate: '%y-01-01',
                            errDealMode: 1,
                            onpicked: function () {
                                this.blur();
                            }
                        })
                    });
                    break;
                case '5':
                    $beginDate.on('focus', function () {
                        WdatePicker({
                            autoShowQS: true,
                            isShowClear: false,
                            firstDayOfWeek: 1,
                            dateFmt: 'yyyy年',
                            isShowToday: false,
                            onpicked: function () {
                                this.blur();
                            }
                        })
                    });
                    break;
            }
        }).trigger('change');
    }

    //下拉框初始化
    var selectInit = function () {
        this.each(function () {
            var dictName = $(this).attr('dict');
            var $select = $(this);
            if (dictName) {
                var dict = window.parent.GLOBAL_PARAMS.DICT_CACHE[dictName];
                if (dict) {
                    $.each(dict, function (i, data) {
                        $select.append('<option value="{0}">{1}</option>'.format(data.key, data.value));
                    })
                }
            } else {
                if ($(this).attr('user-type') === 'reportDateSelect') {
                    $(this).append([
                        '<option value="1">日</option>',
                        '<option value="2">周</option>',
                        '<option value="3">月</option>',
                        '<option value="4">季度</option>',
                        '<option value="5">年</option>'
                    ].join(''));
                    reportDateSelectChange(this);
                }
            }

            //$select.select2();
            var config = $(this).attr('data-options');
            $select.select2();
            if (config) {
                config = $.strToJson(config);

                if ($select.hasClass('.select2-offscreen')) {

                }
                if (config.load !== false) {
                    !dictName && $select._select2Load(config);//dictName为空才去后台加载数据
                    if (config.cascade) {
                        $select.on('change', function () {
                            var $t2 = $(this);
                            if (!$t2.val()) {
                                return;
                            }
                            var cascadeIds = config.cascade.split(',');

                            for (var i = 0, len = cascadeIds.length; i < len; i++) {
                                var _$t = $('#' + cascadeIds[i]),
                                    _options = _$t.getOptions();
                                if (_options.param) {
                                    _options.params = {};
                                    _options.params[_options.param] = $t2.val();
                                }
                                _$t.select2('val', '');
                                _$t._select2Load(_options);
                            }
                        });
                    }
                }
            }
        });
        return this;
    };

    /**
     * 树形弹出框级联事件（用于设置表单时，值填充了，触发相应的事件）
     * @param $obj 树形弹出框对应的值的输入框[type=hidden]
     * @param optionsJSON 配置信息
     */
    function treeDialogCascadeChange($obj, optionsJSON) {
        var _$t = $('#' + optionsJSON.cascade),
            _options = _$t.getOptions();
        if (_$t[0].tagName === 'SELECT') {
            if (_options.param) {
                _options.params = {};
                _options.params[_options.param] = $obj.val();
            }
            //_$t.select2('val', '');
            //_$t._select2Load(_options);
            var $obj = $(_$t);
            if ($obj[0].children.length) {
                $obj.select2('val', '').val('').empty();
            }
            $.ajaxExt({
                url: _options.url,
                data: _options.params || {},
                success: function (data) {
                    if (data) {
                        $.each(data, function (i, item) {
                            $obj.append('<option value="{0}">{1}</option>'.format(item[_options.idField], item[_options.textField]));
                        });
                        var dataVal = $obj.data('data-val');
                        if (dataVal !== undefined) {
                            $obj.select2('val', dataVal).val(dataVal);
                            $obj.removeData('data-val');
                        }
                    }
                }
            })
        }
    }

    $.fn.extend({
        /**
         * 获取元素对应属性的配置信息
         * @param def {JSON} 默认配置信息，不填的话默认{}
         * @param attr {String} 要获取的属性，不填的话默认data-options
         * @returns {JSON}
         */
        getOptions: function (def, attr) {
            var options,
                def = def || {},
                attr = attr || 'data-options',
                customOptions = $(this).attr(attr);
            if ($.trim(customOptions)) {
                options = $.strToJson(customOptions);

                options = $.extend(def, options);
            } else {
                options = def;
            }
            return options;
        },
        /**
         * 初始化表单
         */
        initForm: function () {
            if (placeholderInit) {
                placeholderInit($('input[placeholder],textarea[placeholder]', this));
            }

            selectInit.call($('select', this));

            $(':text[user-type]', this).each(function () {
                if ($(this).attr('user-type') === 'treeDialog') {
                    var options = $(this).attr('data-options') || $(this).data('data-options');
                    if (options) {
                        var optionsJSON = $.strToJson(options);
                        if (optionsJSON.cascade) {
                            $(this).siblings('input[type=hidden]').on('cascadeChange', function () {
                                treeDialogCascadeChange($(this), optionsJSON);
                            });
                        }
                    }
                    $(this).on('click', function () {
                        commonFun.execParentMethod('treeDialog', options, this);
                    });
                }
            });

            return this;
        },
        _select2Load: function (op) {
            var $obj = $(this);
            if ($obj[0].children.length) {
                $obj.select2('val', '').val('').empty();
            }
            $.ajaxExt({
                url: op.url,
                data: op.params || {},
                success: function (data) {
                    if (data) {
                        $.each(data, function (i, item) {
                            $obj.append('<option value="{0}">{1}</option>'.format(item[op.idField], item[op.textField]));
                        });
                        var dataVal = $obj.data('data-val');
                        if (dataVal !== undefined) {
                            $obj.select2('val', dataVal).val(dataVal);
                            if (op.cascade) {
                                $obj.trigger('change');
                            }
                            $obj.removeData('data-val');
                        }
                        op.load !== false && $obj.select2('val', '');//当控件不是被级联的时候才清值
                    }
                }
            })
        },
        getValues: function (isFrame, filter) {
            var val = {};
            var _t = this;
            if (isFrame) {
                _t = $(this)[0].contentWindow.$(filter || 'body');
            }
            $(':text,input[type=hidden],select,textarea', _t).each(function () {
                var name = $(this).attr('name');
                if (name) {
                    val[name] = $(this).val();
                }
            });
            $(':checkbox', _t).each(function () {
                var name = $(this).attr('name');
                if (name) {
                    val[name] = $(this).prop('checked') ? $(this).val() : '';
                }
            });
            $(':radio', _t).each(function () {
                var name = $(this).attr('name');
                if (name) {
                    var value = $(this).prop('checked') ? $(this).val() : '';
                    if (val.hasOwnProperty(name)) {
                        if (val[name] === '' && value !== '') {
                            val[name] = value;
                        }
                    } else {
                        val[name] = value;
                    }
                }
            });
            $('.element-select', _t).each(function () {
                var name = $(this).attr('name');
                if (name) {
                    var value = '';
                    var $active = $('>a.active:eq(0)', this);
                    if ($active.length) {
                        value = $active.attr('data-val') || '';
                    }
                    val[name] = value;
                }
            });
            return val;
        },
        /**
         * 给表单设值
         * @param val {JSON} 要设置的值
         * @param reset 是否先清空表单中的值，不填的话默认为true(清空值)
         */
        setValues: function (val, reset) {
            var prop, propValue, dataType, $input;
            if (reset === undefined) {
                reset = true;
            }
            if (reset) {
                $(this).reset();
            }

            for (prop in val) {
                propValue = val[prop];
                dataType = Object.prototype.toString.call(propValue);
                $input = $(this).find('[name="' + prop + '"]');
                switch (dataType) {
                    case '[object String]':
                    case"[object Number]":
                        if ($input.is(':radio')) {
                            $input.removeAttr('checked');
                            $input.each(function (a, b) {
                                if (b.value == propValue) {
                                    b.checked = true;
                                }
                            })
                        } else {
                            if ($input.hasClass('select2-offscreen')) {
                                if ($input[0].children.length) {
                                    $input.select2('val', propValue).val(propValue);
                                    var optionJSON = $input.getOptions();
                                    if (optionJSON.cascade) {
                                        $input.trigger('change', true);
                                    }
                                    if (optionJSON.load === false) {
                                        $input.data('data-val', propValue);
                                    }
                                } else {//此时select并没有数据，此时给加上data-val供select数据加载完成后使用
                                    $input.data('data-val', propValue);
                                }
                            } else if ($input.is(':checkbox')) {
                                if (propValue == $input.val()) {
                                    $input.attr('checked', true);
                                } else {
                                    $input.attr('checked', false);
                                }
                            } else {

                                $input.val(propValue);
                                if ($input.is('[type=hidden]') && $input.siblings(':text[user-type=treeDialog]').length) {
                                    $input.trigger('cascadeChange');
                                }
                            }
                        }
                        break;
                    case '[object Null]':
                        if ($input.is(':radio')) {
                            $input.removeAttr('checked');
                        } else {
                            if ($input.hasClass('select2-offscreen')) {
                                $input.select2('val', '');
                            } else if ($input.is(':checkbox')) {
                                $input.attr('checked', false);
                            } else {
                                $input.val(propValue);
                            }
                        }
                        break;
                    default :
                        $input.val(propValue);
                }
            }
            return this;
        },
        /**
         * 清空表单中的值
         */
        reset: function (filter) {
            var _t = this;
            if (_t[0].tagName === 'IFRAME') {
                _t = $(this)[0].contentWindow.$(filter || 'body');
            }
            $('input[type=hidden]', _t).val('');
            $.each($('input', _t), function (i, item) {
                switch (item.type) {
                    case 'radio':
                        break;
                    case 'checkbox':
                        $(item).prop('checked', false);
                        break;
                    case 'text':
                        $(item).val('');
                        break;
                }
            });
            $('textarea', _t).val('');

            var $select2 = $('.select2-offscreen', _t);
            if ($select2.length) {
                $select2.select2('val', '');
            }
            return this;
        },
        /**
         * 该节点添加样式cls，同级节点移除样式cls，
         * @param cls {string}不填写的话默认active
         */
        addActiveClass: function (cls) {
            cls = cls || 'active';
            this.addClass(cls).siblings('.' + cls).removeClass(cls);
            return this;
        },
        /**
         * 给视图中包含属性(attrName)的元素设置值
         * @param val {object}具体的值
         * @param attrName {string|null} 自定义的属性节点名称，不填写默认为name
         */
        setViewData: function (val, attrName) {
            attrName = attrName || 'name';
            var els = $('[' + attrName + ']', this);
            $.each(els, function (index, item) {
                var el = $(item);
                var prop = el.attr(attrName);
                var _data = val[prop];
                _data = _data == undefined ? '' : _data;

                var unit = el.attr('data-unit');
                el.text(_data + (unit ? ' ' + unit : ''));
            });
            return this;
        },
        chart: function (op) {
            var con = {
                title: {
                    text: ''
                },
                credits: {
                    enabled: false
                }
            };
            if (op) {

            } else {

            }
            return this;
        },
        /**
         * 根据具体的值对该节点的样式及显示文本进行设置
         * @param val 值
         * @param valConfig {Array} 值对应的样式和显示文本配置
         * [{value: 1, css: '', text: ''},...值为1
         * @param otherConfig {JSON} 其它配置
         * defaultCss:'css1' 默认css为css1
         * {unMatchConfig: {css: 'css1', text: 'text1'}} 未找到配置项（valConfig中没有对应的配置）时
         */
        setView: function (val, valConfig, otherConfig) {
            var _t = this,
                matched = false;//是否找到匹配项
            this.removeClass();
            if (val == null || val === '') {
                matched = true;
                _t.html('');
            } else {
                $.each(valConfig, function (i, _config) {
                    if (_config.value == val) {
                        _config.css && _t.addClass(_config.css);
                        if (_config.text !== null) {
                            _t.html(_config.text);
                        } else {
                            _config.html(val);
                        }
                        matched = true;
                        return false;
                    }
                });
                if (!matched) {
                    _t.html(val);
                }
            }

            otherConfig && $.each(otherConfig, function (prop, _config) {
                switch (prop) {
                    case 'unMatchConfig':
                        if (!matched) {
                            _config.css && _t.addClass(_config.css);
                            _config.text && _t.html(_config.text);
                        }
                        break;
                    case 'defaultCss':
                        if (!_t.hasClass(_config)) {
                            _t.addClass(_config);
                        }
                        break;
                }
            });

        }
    })
})(jQuery);

//树形创建及搜索功能的实现
(function ($) {

    ////输入框获得焦点时，光标放置到最后（IE下，执行focus事件，光标是在最前面，而不是最后面）
    function focus(obj) {
        obj.focus();
        var len = obj.value.length;
        if (document.selection) {
            var sel = obj.createTextRange();
            sel.moveStart('character', len);
            sel.collapse();
            sel.select();
        } else if (typeof obj.selectionStart == 'number'
            && typeof obj.selectionEnd == 'number') {
            obj.selectionStart = obj.selectionEnd = len;
        }
    }

    /**
     * 获取中文的拼音首码
     * @param chinese 要获取拼音首码的中文
     * @returns {String}
     */
    function getPinYin(chinese) {
        var PinYin = window.parent.PinYin || {};
        for (var prop in PinYin) {
            if (PinYin[prop].indexOf(chinese) > -1) {
                chinese = prop.toUpperCase();
                break;
            }
        }
        return chinese;
    }

    /**
     * 查找节点
     * @param node
     * @param searchParams
     * @param searchObj 搜索框对象
     */
    function treeNodeFilter(node, searchParams, searchObj) {


        if (searchParams.searchStr) {
            var key = searchParams.treeObj.setting.data.key.name;
            var chineseArr = node[key].match(/[\u4e00-\u9faf]/gi) || [];//查找节点名中汉字字符集合;
            searchParams.searchStr = searchParams.searchStr.toUpperCase();
            var chinesePinYin = node[key],//拼音
                chinesePinYinCode = node[key];//拼音首码

            $.each(chineseArr, function (index, item) {
                var pinYinStr = getPinYin(item);
                chinesePinYin = chinesePinYin.replace(item, pinYinStr);
                chinesePinYinCode = chinesePinYinCode.replace(item, pinYinStr.length > 1 ? pinYinStr[0] : pinYinStr);
            });

            if ((node[key].indexOf(searchParams.searchStr) > -1 ||
                chinesePinYin.indexOf(searchParams.searchStr) > -1 ||
                chinesePinYinCode.indexOf(searchParams.searchStr) > -1 )) {

                var arr = $(searchParams.searchObj).data('searchNodesResult');
                if (arr.length === 0) {
                    $(searchParams.searchObj).data('currentSearchIndex', 0);
                    searchParams.treeObj.selectNode(node);
                }
                arr.push(node);
                $(searchParams.searchObj).data('searchNodesResult', arr);
                $('#' + node.tId + '_a').css({color: "#A60000", "font-weight": "bold"});
                return;
            }

        }
        $('#' + node.tId + '_a').css({color: "#333", "font-weight": "normal"});
    }
    /**
     * 生成树形结构
     * @param treeConfig 生成树形所需要的配置（参照zTree官方API配置）
     * @param data 数据
     * @param customConfig 自定义的配置选项
     * @returns {jQuery}
     */
    $.fn.createTree = function (treeConfig, data, customConfig) {
        var tree = $.fn.zTree.init(this, treeConfig, data);

        var currentSearchStr;
        if (customConfig) {
            if (customConfig.search) {
                var $search = $(customConfig.search).data('searchNodesResult', []);//查找出来的节点绑定在元素的searchNodesResult上面
                $search.data('currentSearchIndex', -1);
                $search.unbind('keyup.search').on('keyup.search', function (e) {
                    var searchStr = $(this).val();
                    var _t = this;
                    var currentSearchIndex = $(_t).data('currentSearchIndex');
                    var searchNodesResult = $(_t).data('searchNodesResult');
                    if (e.keyCode === 13) {//回车
                        if (currentSearchStr != searchStr) {
                            $(_t).data('currentSearchIndex', 0);
                            $(_t).data('searchNodesResult', []);
                            tree.getNodesByFilter(treeNodeFilter, false, '', {
                                treeObj: tree,
                                searchStr: searchStr,
                                searchObj: _t
                            });

                            if (searchStr === "") {
                                tree.cancelSelectedNode();
                                return;
                            }
                            focus(_t);
                            currentSearchStr = searchStr;
                        } else {
                            if (currentSearchIndex < searchNodesResult.length - 1) {
                                currentSearchIndex++;
                            } else {
                                currentSearchIndex = 0;
                            }
                            $(_t).data('currentSearchIndex', currentSearchIndex);
                            tree.selectNode(searchNodesResult[currentSearchIndex]);
                            focus(_t);
                        }
                    }


                });
            }
        }
        return tree;
    };
})(jQuery);

//jquery.cookie
(function($){

    var pluses = /\+/g;

    function encode(s) {
        return config.raw ? s : encodeURIComponent(s);
    }

    function decode(s) {
        return config.raw ? s : decodeURIComponent(s);
    }

    function stringifyCookieValue(value) {
        return encode(config.json ? JSON.stringify(value) : String(value));
    }

    function parseCookieValue(s) {
        if (s.indexOf('"') === 0) {
            // This is a quoted cookie as according to RFC2068, unescape...
            s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
        }

        try {
            // Replace server-side written pluses with spaces.
            // If we can't decode the cookie, ignore it, it's unusable.
            // If we can't parse the cookie, ignore it, it's unusable.
            s = decodeURIComponent(s.replace(pluses, ' '));
            return config.json ? JSON.parse(s) : s;
        } catch(e) {}
    }

    function read(s, converter) {
        var value = config.raw ? s : parseCookieValue(s);
        return $.isFunction(converter) ? converter(value) : value;
    }

    var config = $.cookie = function (key, value, options) {

        // Write

        if (arguments.length > 1 && !$.isFunction(value)) {
            options = $.extend({}, config.defaults, options);

            if (typeof options.expires === 'number') {
                var days = options.expires, t = options.expires = new Date();
                t.setMilliseconds(t.getMilliseconds() + days * 864e+5);
            }

            return (document.cookie = [
                encode(key), '=', stringifyCookieValue(value),
                options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
                options.path    ? '; path=' + options.path : '',
                options.domain  ? '; domain=' + options.domain : '',
                options.secure  ? '; secure' : ''
            ].join(''));
        }

        // Read

        var result = key ? undefined : {},
        // To prevent the for loop in the first place assign an empty array
        // in case there are no cookies at all. Also prevents odd result when
        // calling $.cookie().
            cookies = document.cookie ? document.cookie.split('; ') : [],
            i = 0,
            l = cookies.length;

        for (; i < l; i++) {
            var parts = cookies[i].split('='),
                name = decode(parts.shift()),
                cookie = parts.join('=');

            if (key === name) {
                // If second argument (value) is a function it's a converter...
                result = read(cookie, value);
                break;
            }

            // Prevent storing a cookie that we couldn't decode.
            if (!key && (cookie = read(cookie)) !== undefined) {
                result[name] = cookie;
            }
        }

        return result;
    };

    config.defaults = {};

    $.removeCookie = function (key, options) {
        // Must not alter options, thus extending a fresh object...
        $.cookie(key, '', $.extend({}, options, { expires: -1 }));
        return !$.cookie(key);
    };
})(jQuery);
